function Merge-HashTable {
    param(
        [hashtable] $default, # your original set
        [hashtable] $uppend # the set you want to update/append to the original set
    )

    # clone for idempotence
    $default1 = $default.Clone() ;

    # remove any keys that exists in original set
    foreach ($key in $uppend.Keys) {
        if ($default1.ContainsKey($key)) {
            $default1.Remove($key) ;
        }
    }

    # union both sets
    return $default1 + $uppend ;
}

function Clone-Member
{
   [cmdletbinding(DefaultParameterSetName="none")]
    Param( 
        [Parameter(Mandatory=$true,ValueFromPipeline=$false)]
        [PsObject] 
        $Source,

        [Parameter(Mandatory=$true,ValueFromPipeline=$false)]
        [PsObject] 
        $Target,

        [Parameter(Mandatory=$false,ValueFromPipeline=$false)]
        [Scriptblock] 
        $Filter,

        [Parameter(Mandatory=$false,ValueFromPipeline=$false)]
        [Switch] 
        $All

        )
    Process
    {
        $members = $Source | Get-Member -MemberType NoteProperty, ScriptProperty
        if ($Filter)
        {
            $members = $members | ? $Filter
        }


        $members | ForEach-Object {
            $shortDefinition = ($_.Definition -split " ")[0].Trim()
            #Fix Powershell V5 / V4
            $shortDefinition = $shortDefinition.replace("System.Object[]","Object[]")
            $shortDefinition = $shortDefinition.replace("System.Collections.Hashtable","hashtable")

            $name = $_.Name
            Write-Verbose "Clone Member : Identiy property named '$name' with definition type '$shortDefinition'"

            switch($shortDefinition)
            {
                "object[]" {
                    if (-not $All) {continue}
                    $Target | Add-Member -MemberType NoteProperty -Name $name -Value @()
                    foreach($childElement in $Source.$name)
                    {
                        $value = New-Object PsObject
                        Clone-Member -Target $value -Source $childElement -All:$All
                        $Target.$name += $value
                    }

                }
                "hashtable" {
                    if (-not $All) {continue}
                    $Target | Add-Member -MemberType NoteProperty -Name $name -Value @{}
                    $keys = $Source.$name.keys
                    foreach($key in $keys)
                    {
                        #Write-debug "Clone-Member : Start clone-member for hashtable element '$key'"
                        $value = New-Object PSObject
                        Clone-Member -Target $value -Source $Source.$name[$key] -All:$All
                        $Target.$name.add($key,$value)
                    }

                }
				"System.Management.Automation.PSCustomObject" {
                    if (-not $All) {continue}
					$value = New-Object PSObject
                    Clone-Member -Target $value -Source $Source.$name -All:$All
					$Target | Add-Member -MemberType NoteProperty -Name $name -Value $value
				}
                default {
					$Target | Add-Member -MemberType NoteProperty -Name $name -Value $Source.$name
                }
            }
            
        }
    }

}

